package com.android.bonn.fast.net.interceptor.log;

import android.text.TextUtils;
import android.util.Log;


import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

public final class HttpLoggingInterceptor2 implements Interceptor {

    private static final Charset UTF8 = Charset.forName("UTF-8");

    private final boolean isDebug;
    private Builder builder;

    private HttpLoggingInterceptor2(Builder builder) {
        this.builder = builder;
        this.isDebug = builder.isDebug;
    }


    @Override
    public Response intercept(Chain chain) throws IOException {

        Request request = chain.request();
        long st = System.nanoTime();


        List<String> segmentList = ((Request) request.tag()).url().encodedPathSegments();
        long chainMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - st);
        Response response = chain.proceed(request);
        String header = response.headers().toString();
        int code = response.code();
        boolean isSuccessful = response.isSuccessful();
        String bodyString = response.body().string();
        Logger.printJsonResponse(builder, request, chainMs, isSuccessful, code, header, bodyString, segmentList);

        Request cloneRequest = chain.request();
        MediaType contentType = null;
        if (cloneRequest.body() != null)
            contentType = cloneRequest.body().contentType();
        ResponseBody body = ResponseBody.create(contentType, bodyString);

        return response.newBuilder().body(body).build();
    }

    public static class Builder {

        private static String TAG = "LoggingI";
        private boolean isDebug;
        private int type = Log.DEBUG;
        private String requestTag;
        private String responseTag;
        private Headers.Builder builder;

        public Builder() {
            builder = new Headers.Builder();
        }

        int getType() {
            return type;
        }

        Headers getHeaders() {
            return builder.build();
        }

        String getTag(boolean isRequest) {
            if (isRequest) {
                return TextUtils.isEmpty(requestTag) ? TAG : requestTag;
            } else {
                return TextUtils.isEmpty(responseTag) ? TAG : responseTag;
            }
        }

        /**
         * @param name  Filed
         * @param value Value
         * @return Builder
         * Add a field with the specified value
         */
        public Builder addHeader(String name, String value) {
            builder.set(name, value);
            return this;
        }

        /**
         * Set request and response each log tag
         *
         * @param tag general log tag
         * @return Builder
         */
        public Builder tag(String tag) {
            TAG = tag;
            return this;
        }

        /**
         * Set request log tag
         *
         * @param tag request log tag
         * @return Builder
         */
        public Builder request(String tag) {
            this.requestTag = tag;
            return this;
        }

        /**
         * Set response log tag
         *
         * @param tag response log tag
         * @return Builder
         */
        public Builder response(String tag) {
            this.responseTag = tag;
            return this;
        }

        /**
         * @param isDebug set can sending log output
         * @return Builder
         */
        public Builder loggable(boolean isDebug) {
            this.isDebug = isDebug;
            return this;
        }

        /**
         * @param type set sending log output type
         * @return Builder
         * @see Log
         */
        public Builder log(int type) {
            this.type = type;
            return this;
        }

        public HttpLoggingInterceptor2 build() {
            return new HttpLoggingInterceptor2(this);
        }
    }
}